package com.harun;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;


/**
 * don't use in TreeSet, because special comparable implementation
 * */
public class User implements Comparable<User> {

	private String userId;
	
	private TreeSet<Image> images = new TreeSet<Image>();

	private Map<Integer, Set<Image>> histogramMap = new HashMap<Integer, Set<Image>>();
	
	public User(String userId) {
		this.userId = userId;
	}

	public String getUserId() {
		return userId;
	}
	
	public Set<Image> getImages() {
		return Collections.unmodifiableSet(images);
	}	
	
	public void setImages(TreeSet<Image> images) {
		this.images = images;
		histogramMap.clear();
		for (Image image : images) 
			addImageToHistogramMap(image);
	}
	
	public Map<Integer, Set<Image>> getHistogramMap() {
		return Collections.unmodifiableMap(histogramMap);
	}
	
	public void addImage(Image image) {
		images.add(image);
		addImageToHistogramMap(image);
	}
	
	private void addImageToHistogramMap(Image image) {
		Set<Image> set = histogramMap.get(image.getClsId());
		if(set == null)
			histogramMap.put(image.getClsId(), set = new TreeSet<Image>());
		set.add(image);
	}
	
	public List<Long> getImageIdList() {
		List<Long> set = new ArrayList<Long>();
		for (Image image : images) 
			set.add(image.getImageId());
		return set;
	}
	
//	public Map<Integer, Set<Image>> getImageHistogramMap() {
//		Map<Integer, Set<Image>> map = new HashMap<Integer, Set<Image>>();
//		for (Image image : images) {
//			Set<Image> set = map.get(image.getClsId());
//			if(set == null)
//				map.put(image.getClsId(), set = new TreeSet<Image>());
//			set.add(image);
//		}
//		return map;
//	}
	
	public List<Integer> getFavoriteClusterId() {
		
		Map<Integer, Integer> map = new HashMap<Integer, Integer>();
		
		for (Entry<Integer, Set<Image>> entry : histogramMap.entrySet()) 
			map.put(entry.getKey(), entry.getValue().size());
		
		List<Map.Entry<Integer, Integer>> tmpList = new LinkedList<Map.Entry<Integer, Integer>>(map.entrySet());

		Collections.sort(tmpList, new Comparator<Map.Entry<Integer, Integer>>() {
			public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
				return (o2.getValue()).compareTo(o1.getValue());
			}
		});

		List<Integer> list = new ArrayList<Integer>();
		for (Map.Entry<Integer, Integer> entry : tmpList) 
			list.add(entry.getKey());
		
		return list;
	}
	
	public int compareTo(User o) {
		if(o == null)
			throw new NullPointerException();
		
		return ((Integer)o.images.size()).compareTo(this.images.size());
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((userId == null) ? 0 : userId.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) return true;
		if (obj == null) return false;
		if (getClass() != obj.getClass())
			return false;
		User other = (User) obj;
		if (userId == null) {
			if (other.userId != null)
				return false;
		} else if (!userId.equals(other.userId))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "User [userId=" + userId + ", images=" + images.size() + "]";
	}
	
}
